<?php

class User extends CI_Model {

	function __construct() {
		parent::__construct();
	}

	/**
	 * Check if user is logged in
	 * @return  bool
	 */
	public function is_logged() {
		if ( $this->session->userdata('logged_in') ) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	/**
	 * Check if user is an administrator
	 * @return  bool
	 */
	public function is_administrator() {
	  if ( $this->session->userdata('role') == 'administrator' ) {
		return TRUE;
	  } else {
		return FALSE;
	  }
	}

	/**
	 * Check if user is a lecturer
	 * @return  bool
	 */
	public function is_lecturer() {
	  if ( $this->session->userdata('role') == 'lecturer' ) {
		return TRUE;
	  } else {
		return FALSE;
	  }
	}

	/**
	 * Check if user is a tutor
	 * @return  bool
	 */
	public function is_tutor() {
	  if ( $this->session->userdata('role') == 'tutor' ) {
		return TRUE;
	  } else {
		return FALSE;
	  }
	}

	/**
	 * Check if user is a student
	 * @return  bool
	 */
	public function is_student() {
	  if ( $this->session->userdata('role') == 'student' ) {
		return TRUE;
	  } else {
		return FALSE;
	  }
	}

	/**
	 * Returns all information about the current user
	 * @param  user_id  (Optional)
	 * @param role (Optional)
	 * @return array
	 */
	public function get_user_data( $user_id = NULL , $role = NULL ) {
		// TODO: Include information about groups, assignments etc.
	   
		// Fields to select
		$this->db->select('*');
		// Select from the users table
		$this->db->from('users');
		$this->db->join('classes', 'users.class_id = classes.class_id', 'left');
		// Check if a user_id has been set, otherwise retrieve all user info
		if ( isset($user_id) ) {
		  $this->db->where('user_id', $user_id);
		}
		if ( isset($role) ) {
		  $this->db->where('role', $role);
		}
		// Get results
		$query = $this->db->get();

		// If a user_id has been set return a row
		// Otherwise, return all rows
		if ( isset($user_id) ) {
		  $result = $query->row_array();
		  return $result;
		} else {
		  $result = $query->result_array();
		  return $result;
		}
	}

	/**
	 * Authenticate user
	 * @param string username
	 * @param string password 
	 * @return  bool
	 */
	public function login($qut_id, $password) {

		// TODO: validate data
		// TODO: Possibly allow login via email or QUT ID?

		// Check if logged in already
		if ( $this->session->userdata('logged_in') ) {
			return TRUE;
		}

		// Check if the user exists in the database
		$query = $this->db->get_where('users', array('qut_id' => $qut_id) );

		if ($query->num_rows() > 0) {
			// Get all the users data
			$user_data = $query->row_array(); 

			if ( do_hash($password, 'md5') == $user_data['password'] ) {
				
				// User authenticated

				//Destroy old session and create a new one
				$this->session->sess_destroy();
				$this->session->sess_create();

				// Set session data
				$data['logged_in'] = TRUE;
				$data['user_id'] = $user_data['user_id'];
				$data['qut_id'] = $user_data['qut_id'];
				$data['name'] = $user_data['first_name'];
				$data['role'] = $user_data['role'];
				$this->session->set_userdata($data);

		  return TRUE;

			} else {
				// Incorrct Password
				$error[] = 'Incorrect Password!';
			}

		} else {
			// Username incorrect / User does not exist
			$error[] = 'Incorrect Username!';
		}

	  // Return true false and also set session flashdata
	  if ( isset( $error ) ) {
		// Set array of errors into flash data (stored for one server request only)
		$this->session->set_flashdata('errors', $error);
		return false;
	  } else {
		// Set array of notices into flash data
		if ( isset($notice) ) { $this->session->set_flashdata('notices', $notice); }
		return true;
	  }
	}


	/**
	 * Logout
	 * @return	bool
	 */
	function logout() {
	if ( $this->session->sess_destroy() ) {
	  return TRUE;
	} else {
		$this->session->set_flashdata('errors', 'An error occurred, please try again.' );
		return FALSE;
	}
	}


	/**
	 * Add a user to the database
	 * @param data array
	 * @param  skip_errors Shhould flash data be set?
	 * @return  bool
	 */
   public function add_user($data, $skip_errors = FALSE, $email_password=false) {



		// Check if user already exists
	  if ( $this->_check_user_exists( $data['qut_id'], $data['email'] ) ) {
		if ( ! $skip_errors ) { $this->session->set_flashdata('errors', 'Error: This user has already been added.' ); }
		return FALSE;
	  } 
	  if ( $this->_check_user_exists( $data['qut_id'] ) ) {
		// QUT ID already in use
		if ( ! $skip_errors ) { $this->session->set_flashdata('errors', 'Error: The specified QUT ID is already in use.' ); }
		return FALSE;
	  } 
	  if ( $this->_check_user_exists( null, $data['email'] ) ) {
		// Email address already in database
		if ( ! $skip_errors ) { $this->session->set_flashdata('errors', 'Error: The specified email address is already in use.' ); }
		return FALSE;
	  }

		// Get a password for the user
		$data['password'] = $this->_create_password();

		// REMOVE THIS (Shows the password created for the user if you need it)
		echo '<div style="display:none;">' . $data['password'] . '</div>';

		if ($email_password) {
			$this->_email_user_confirmation($data);
		}

		$user_password = $data['password'];

		// Once password is sent to user encrypt the password for storing in the database
		$data['password'] = do_hash($data['password'], 'md5');

		// Returns true on success
		if ( $this->db->insert('users', $data) ) {
			if ( ! $skip_errors ) { $this->session->set_flashdata('notices', 'User added successfully.' ); }
			if ($email_password == false) {
				if ( ! $skip_errors ) { $this->session->set_flashdata('notices', 'User added successfully. User password: ' . $user_password ); }
				return true;
			}
			return TRUE;
		} else {
			if ( ! $skip_errors ) { $this->session->set_flashdata('errors', 'An error has occured, please try again.' ); }
			return FALSE;
		}		 

   }

   /**
	* Import a user from a CSV file
	* @param arr $config Configuration (file_path, named_fields, separator, enclosure)
	* @param str $role The role of the user (Student, etc)
	* @return bool
	*/
   public function import_users( $config , $role ) {

   		// Validate some stuff
   		if ( ! isset( $config['file_path'] ) ) { return FALSE; }
   		if ( ! isset( $config['named_fields'] ) ) { $config['named_fields'] = TRUE; }
   		if ( ! isset( $config['separator'] ) ) { $config['separator'] = ','; }
   		if ( ! isset( $config['enclosure'] ) ) { $config['enclosure'] = '"'; }

   		// Set some variables
   		$file_path = $config['file_path'];
   		$named_fields = $config['named_fields'];
   		$separator = $config['separator'];
   		$enclosure = $config['enclosure'];
   		$max_row_size = 4096;
   		$content = false;
   		$file = fopen( $config['file_path'] , 'r');

   		if( $named_fields ) {
            $fields = fgetcsv($file, $max_row_size, $separator, $enclosure);
        }

        while( ($row = fgetcsv($file, $max_row_size, $separator, $enclosure)) != false ) {            
            if( $row[0] != null ) { // skip empty lines
                if( !$content ) {
                    $content = array();
                }
                if( $named_fields ) {
                    $items = array();

                    foreach( $fields as $id => $field ) {
                        if( isset($row[$id]) ) {
                            $items[$field] = $row[$id];    
                        }
                    }
                    $items['role'] = $role;
                    $content[] = $items;
                } else {
                    $content[] = $row;
                }
            }
        }
        fclose($file);
       
       	for ($i=0; $i < count($content); $i++) { 
       		// Add the user and skip error output
       		if( ! $this->add_user($content[$i] , TRUE) ) {
       			// Something went wrong... OoPs
       			return false;
       		}
       	}
       	// No problems!
       	return true;
   }

   /**
	* Remove a user by user id
	* @param int $user_id The users id
	* @return bool
	*/
   public function remove_user($user_id) {
	  if ( $this->db->delete('users', array('user_id' => $user_id) ) ) {
		$this->session->set_flashdata('notices', 'User deleted successfully.' );
		return TRUE;
	  } else {
		$this->session->set_flashdata('errors', 'An error occurred, please try again.' );
		return FALSE;
	  }
   }

   /**
	 * Change a users password
	 * @param int user_id - The user ID number (Not QUT ID)
	 * @param string password - The users new password
	 * @return  bool
	 */
   public function change_password($user_id, $password) {

	  // Encrypt the password for storing in the database
	  $password = do_hash($password, 'md5');

	  // Data to be updated
	  $data['password'] = $password;

	  // Select the correct user
	  $this->db->where('user_id', $user_id);

	  // Returns true on success
	  if ( $this->db->update('users', $data) ) {
		$this->session->set_flashdata('notices', 'Password updated successfully.' );
		return TRUE;
	  } else {
		$this->session->set_flashdata('errors', 'An error has occured, please try again.' );
		return FALSE;
	  }    

   }

   /**
	 * Change a users email address
	 * @param int user_id - The user ID number (Not QUT ID)
	 * @param string email - The users new email address
	 * @return  bool
	 */
   public function change_email($user_id, $email) {

	  // Data to be updated
	  $data['email'] = $email;

	  // Select the correct user
	  $this->db->where('user_id', $user_id);

	  // Returns true on success
	  if ( $this->db->update('users', $data) ) {
		$this->session->set_flashdata('notices', 'Email address updated successfully.' );
		return TRUE;
	  } else {
		$this->session->set_flashdata('errors', 'An error has occured, please try again.' );
		return FALSE;
	  }    

   }

   /**
	 * Change a users class
	 * @param int user_id - The user ID number (Not QUT ID)
	 * @param string class_id - The users new class id
	 * @return  bool
	 */
   public function change_class($user_id, $class_id) {
	  // Data to be updated
	  $data['class_id'] = $class_id;
	  // Select the correct user
	  $this->db->where('user_id', $user_id);

	  // Returns true on success
	  if ( $this->db->update('users', $data) ) {
		return TRUE;
	  } else {
		return FALSE;
	  }    
   }

   /**
	* Check if a user exists be checking for their QUT ID and email address (both parameters are optional)
	*/
   private function _check_user_exists( $qut_id=NULL, $email=NULL ) {

		$this->db->select('user_id');
		$this->db->from('users');

		if ( isset($qut_id) ) {
		  $this->db->where('qut_id', $qut_id);
		}

		if ( isset($email) ) {
		  $this->db->where('email', $email);
		}

		$query = $this->db->get();

		// Return true if any results found
		if ($query->num_rows() > 0) {
		  return TRUE;
		} else {
		  return FALSE;
		}
	}


	public function get_student_marks($class_id=false) {
		$this->db->select('qut_id, first_name, last_name, result, %');
		$this->db->from('users');
		$this->db->where('role', 'student'); 
		$this->db->join('classes', 'users.class_id = classes.class_id','left');

		// Restrict by class
		if ( $class_id && $class_id != 'all' ) { 
			$this->db->where('classes.class_id', $class_id); 
		}
		
		$query = $this->db->get();
		$result = $query->result_array();
		return $result;
	}


   /**
	* Send an email the the user with account details
	*/
   private function _email_user_confirmation($data) {

	  // TODO: Admin settings for email etc.

		$message = 'Hi '. $data['first_name'] .', Your blueboard account has been created. You can login with your QUT ID ('. $data['qut_id']. ') and password "'. $data['password'] . '"';

		// Load the CI email library
		$this->load->library('email');
	  // Load the settings model (We need the administrator email/name)
	  $this->load->model('settings');

		$this->email->from($this->settings->get_setting('administrator_email'), $this->settings->get_setting('administrator_name'));
		$this->email->to($data['email']); 
		$this->email->subject("Your Blueboard Account Information");
		$this->email->message($message);	

		if ( $this->email->send() ) {  
			return TRUE;
		} else {
			return FALSE;
		}	
   }

   /**
	* Create a random 10 character password
	*/
   private function _create_password() {

		$password_length = 10;

		$alfa = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
		$token = "";

		for($i = 0; $i < $password_length; $i ++) {
			$token .= $alfa[rand(0, strlen($alfa) - 1)];
		}    
		return $token;
   }

   /**
	* Returns an array from a csv file
	*/
	private function _extract_csv_data() {

	}

}